package dp.mobile.level;

import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.util.Log;
import org.w3c.dom.Node;
import dp.mobile.game.Tileset;
import dp.mobile.glwrapper.GameRenderer;
import dp.mobile.glwrapper.MapRenderer;
import dp.mobile.system.Utilities;
import dp.mobile.system.XMLReader;

public class Map {
	private static final String TAG = "Map";
	
	protected Map() {
		//initialize
		mWidth		= 1;
		mHeight		= 1;
		mTiles		= null;
		mNodes		= null;
		mNodeBuffer = null;
		mTileset	= null;
		mRenderer 	= null;
		mDelayedInvalidate = false;
	}

	public Map(String mapStr, String tileset, String nodes) {
		//Default
		this();

        String tilesetImg = null, buildable = null, offlineNodeImg = null, onlineNodeImg = null;
        
        org.w3c.dom.Node root = XMLReader.instance().parseXML(Utilities.DATA_FOLDER + "/" + tileset);

		//For each children
        int childCount = root.getChildNodes().getLength();
        for(int i = 0; i< childCount; ++i){
			//Read tag
        	Node child		= root.getChildNodes().item(i);
        	if (child.getNodeType() == Node.TEXT_NODE) continue;
        	
            String tag 		= child.getNodeName();
			String value 	= child.getFirstChild().getNodeValue();

			//Save based on tag
            if(tag.equals("image"))				tilesetImg 		= value;
            else if(tag.equals("offline-node"))	offlineNodeImg	= value;
            else if(tag.equals("online-node"))	onlineNodeImg	= value;
			else if(tag.equals("buildable"))	buildable 		= value;
            // backward compatibility
            else if (tag.equals("node"))		offlineNodeImg	= value;
        }
        
        if (onlineNodeImg == null) 
        	onlineNodeImg = offlineNodeImg;

		//Create tileset
		mTileset = new Tileset(Utilities.TILESET_FOLDER + "/" + tilesetImg, Utilities.TILESET_FOLDER + "/" + offlineNodeImg, Utilities.TILESET_FOLDER + "/" + onlineNodeImg, buildable);
		
		//Get height
		if (System.getProperty("line.separator") != null)	mHeight = mapStr.split(System.getProperty("line.separator")).length;
		else												mHeight = mapStr.split("" + (char)10).length;

		//Get tiles
		String[] splitted	= mapStr.split(";");
		for (int i = 0; i < splitted.length; ++i) splitted[i] = splitted[i].trim();
		mWidth				= splitted.length / mHeight;
		mTiles				= new int[mWidth][mHeight];
		
		//Fill the mTiles
		for(int i = 0; i < mHeight; ++i)
			for(int j = 0; j < mWidth; ++j)
				mTiles[j][i] = Integer.parseInt(splitted[(i*mWidth) + j]);
		
		// get nodes
		mNodes				= new ArrayList<dp.mobile.entity.Node>();
		mNodeBuffer			= new short[mWidth][mHeight];
		splitted			= nodes.split(";");
		for (int i = 0; i < splitted.length; ++i) splitted[i] = splitted[i].trim();
		for (int i = 0; i < splitted.length; ++i) {
			String[] pos = splitted[i].split(",");
			if (pos.length < 2) continue;
			final int x = Integer.parseInt(pos[0]);
			final int y = Integer.parseInt(pos[1]);
			
			mNodeBuffer[x][y] = 1;
			mNodes.add(new dp.mobile.entity.Node(x, y, mTileset.getOfflineNodeImage(), mTileset.getOnlineNodeImage()));
		}
	}
	
	public ArrayList<dp.mobile.entity.Node> getNodes () {
		return mNodes;
	}

    public boolean isTileBuildable(int x, int y){
    	return (mTileset.isTileBuildable(mTiles[x][y]));
    }
    
    public boolean isNode(int x, int y) {
    	return mNodeBuffer[x][y] > 0;
    }
    
    public boolean isOnlineNode(int x, int y) {
    	return mNodeBuffer[x][y] > 1;
    }

	public int getWidth() {
		return mWidth;
	}

	public int getHeight() {
		return mHeight;
	}

	public void draw(GL10 gl, int startX, int startY, int endX, int endY) {
		//Draw tiles
		/*for (int y = endY - 1; y >= startY; y--) {
			for (int x = startX; x < endX; x++) {
				//Draw
				GameRenderer.instance().draw(gl, 
						mTileset.getTile(mTiles[x][y]).Texture, 
						mTileset.getTile(mTiles[x][y]).Crop,
						((x - startX) * Utilities.TILE_WIDTH), 
						((y - startY) * Utilities.TILE_HEIGHT),
						Utilities.TILE_WIDTH, Utilities.TILE_HEIGHT,
						0);
			}
		}*/
		if (mRenderer == null) {
			mRenderer = new MapRenderer(mTileset, mTiles, mNodes);
			if (mDelayedInvalidate)
				mRenderer.invalidateVBO();
			mDelayedInvalidate = false;
		}
		
		mRenderer.draw((GL11)gl, startX, startY, endX, endY);
	}
	
	public void onPause() {
		if (mRenderer != null)
			mRenderer.invalidateVBO();
		else
			mDelayedInvalidate = true;
	}
	
	
	//Data
	protected int 			mWidth;
	protected int 			mHeight;
	protected int[][] 		mTiles;
	protected short[][]		mNodeBuffer;
	protected Tileset		mTileset;
	protected MapRenderer 	mRenderer;
	protected boolean		mDelayedInvalidate;

	protected ArrayList<dp.mobile.entity.Node> 	mNodes;
}
